package com.yudaob2b.elong.controller.domestic.data;

import com.alibaba.fastjson.JSONObject;
import com.yudaob2b.business.service.ElongHotelInventoryService;
import com.yudaob2b.business.service.ElongHotelListService;
import com.yudaob2b.business.service.RedisLockService;
import com.yudaob2b.common.utils.ABSResponse;
import com.yudaob2b.common.utils.DateUtil;
import com.yudaob2b.common.utils.ListUtil;
import com.yudaob2b.common.utils.PageUtil;
import com.yudaob2b.elong.constant.Constant;
import com.yudaob2b.elong.constant.RedisConstant;
import com.yudaob2b.elong.service.HotelInventoryService;
import com.yudaob2b.elong.service.HttpStaticService;
import com.yudaob2b.elong.task.DataInvLocalTask;
import org.frameworkset.elasticsearch.ElasticSearchHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 国内酒店-房态库存
 *
 * @author Kidd.Tan
 * @email 298023780@qq.com
 * @date 7/15/18 4:57 PM
 */
@RestController
@RequestMapping("/api/data/inv")
public class ApiDataInventoryController {
    private static Logger dataInvLogger = LoggerFactory.getLogger("dataInvLogger");

    // redis业务锁key
    private final String REDIS_LOCK_KEY_INV_LOCAL = "lock_inv_local";

    @Autowired
    private HttpStaticService httpStaticService;

    @Autowired
    private ElongHotelListService elongHotelListService;

    @Autowired
    private ElongHotelInventoryService elongHotelInventoryService;

    @Autowired
    private RedisLockService redisLockService;

    @Autowired
    private HotelInventoryService hotelInventoryService;

    @Resource(name = "dataInvLocalTaskExecutor")
    private ThreadPoolTaskExecutor dataInvLocalTaskExecutor;

    @Resource(name = "dataInvDbTaskExecutor")
    private ThreadPoolTaskExecutor dataInvDbTaskExecutor;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 全量落地
     */
    @RequestMapping("/local")
    public void go() {
        dataInvLogger.info("启动艺龙国内酒店－房态库存全量，开始时间：{} ", DateUtil.format(new Date(), DateUtil.PATTERN_CLASSICAL));
        long start = System.currentTimeMillis();

        // 重置增量的参数，当前时间5分钟前
        hotelInventoryService.updateIncrLastIdInfo("", DateUtil.rollDate(new Date(), 0, -Constant.INCR_AHEAD_MINUTE));

        try {
            // redis业务锁
            if (redisLockService.lock(REDIS_LOCK_KEY_INV_LOCAL, 0)) {
                int invSearchSize = 10;

                // 查询酒店id参数集合
                Map<String, Object> condition = new HashMap<>();
                condition.put("status", "0");
                int page = 1;
                int pageSize = 10000;

                while (true) {
                    try {
                        PageUtil.setPage(page, pageSize, condition);
                        List<String> hotelIdList = elongHotelListService.queryHotelIdListPage(condition);
                        if (hotelIdList.size() == 0) {
                            break;
                        }

                        List<List<String>> pageList = ListUtil.split(hotelIdList, invSearchSize);
                        for (List<String> pageHotelIdList : pageList) {
                            DataInvLocalTask dataInvLocalTask = new DataInvLocalTask(
                                    pageHotelIdList, httpStaticService
                                    , hotelInventoryService, dataInvDbTaskExecutor
                                    , elongHotelInventoryService, redisTemplate
                                    , ElasticSearchHelper.getRestClientUtil()
                            );
                            //Thread.sleep(1000);
                            dataInvLocalTaskExecutor.execute(dataInvLocalTask);
                        }
                    } catch (Exception e) {
                        dataInvLogger.info("全量同步房态库存异常：", e);
                        e.printStackTrace();
                    } finally {
                        page++;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            redisLockService.unlock(REDIS_LOCK_KEY_INV_LOCAL + "_redis_lock");
        }

        dataInvLogger.info("完成艺龙国内酒店－房态库存全量，当前时间：{}，一共耗时：{} ", DateUtil.format(new Date(), DateUtil.PATTERN_CLASSICAL), (System.currentTimeMillis() - start));
    }

    /**
     * 查询增量队列个数
     *
     * @return
     */
    @RequestMapping("/queryIncrInvInfo")
    public ABSResponse queryIncrInvInfo() {
        ABSResponse response = new ABSResponse();
        long listSize = redisTemplate.opsForList().size(RedisConstant.REDIS_INCR_INV_UPDATE_LASTID_LIST_KEY);
        Object updateTimeObj = redisTemplate.opsForValue().get(RedisConstant.REDIS_INCR_INV_UPDATE_TIME_KEY);
        Date updateTime = updateTimeObj == null ? null : (Date) updateTimeObj;
        Object lastIdObj = redisTemplate.opsForValue().get(RedisConstant.REDIS_INCR_INV_LASTID_KEY);
        String lastId = lastIdObj == null ? null : lastIdObj.toString();
        Object lockObj = redisTemplate.opsForValue().get(REDIS_LOCK_KEY_INV_LOCAL);
        String lock = lockObj == null ? null : lockObj.toString();

        JSONObject resultJson = new JSONObject();
        response.put("listSize", listSize);
        response.put("updateTime", updateTime);
        response.put("lastId", lastId);
        response.put("lock", lock);

        response.ok(resultJson);
        return response;
    }
}
